#!/usr/bin/env python
# encoding: utf-8
"""
questionmodel.py

Created by AlanYang on 2011-06-04.
Copyright (c) 2011 __MyCompanyName__. All rights reserved.
"""
import os
import time
import types
import hashlib
import cPickle
import pymongo
import memcache

from flask import g
from mongomodel import MongoModel
from application import app
from apps.search.searchmodel import index,update
from apps.search import searchengine

@app.signal_getquestion.connect
def getquestionex(sender,**kv):
    qid = kv.pop('qid',None)
    return getquestion(qid) if qid else False

@app.signal_tagquestions.connect
def gettagquestions(sender,**kv):
    if not kv.has_key('tag'):
        return []
    tag = kv.get('tag')
    skip = kv.get('skip',0)
    limit = kv.get('limit',10)
    return QuestionModel().gettagquestions(tag=tag,skip=skip,limit=limit)

def getquestion(qid):
    return QuestionModel().getquestion(qid)

@index(['title','summary','tags'],name='question')
def setquestion(question):
    qid = QuestionModel(**question).commit()
    if qid:
        uid = question['uid']
        _r = app.signal_addquestion.send(__name__,uid=uid,qid=qid)
    return qid

def getnewestquestions(typeid=0,skip=0,limit=10,sort=pymongo.DESCENDING):
    return QuestionModel().getnewestquestions(typeid, skip, limit, 'timestamp',sort)

def getunanswers(typeid=0,skip=0,limit=10,sort=pymongo.DESCENDING):
    return QuestionModel().getunanswers(typeid, skip, limit, 'timestamp',sort)

def getunrightquestions(typeid=0,skip=0,limit=10,sort=pymongo.DESCENDING):
    return QuestionModel().getunrightquestions(typeid, skip, limit, 'timestamp',sort)

@update(['answer','uid'],'$push','answers','question')
def setanswer(qid,answer):
    result = QuestionModel().addanswer(qid,**answer)
    if result:
        uid = answer['uid']
        _r = app.signal_addanswer.send(__name__,uid=uid,qid=qid,answer=answer['answer'])
    return result

def searchquestion(s,skip=0,limit=10):
    result = QuestionModel().search(s, skip, limit)
#    raise TypeError,result
    return result


class QuestionModel(MongoModel):
    def __init__(self,**question):
        self.question = question
        if not getattr(g, 'mongo',None):
            g.mongo = pymongo.Connection(app.config['MONGO_HOST'],app.config['MONGO_PORT'])
        if not getattr(g, 'memcache',None):
            g.memcache = memcache.Client(app.config['CACHE_MEMCACHED_SERVERS'])
        MongoModel.__init__(self, g.mongo.freeasker.question, '_id', g.memcache, app.config['QUESTION_EXPIRE'])
        
    def __set_cache__(self, question):
        return MongoModel.__set_cache__(self, question,time=self.expire)
    
    def __hash_question__(self,title):
        if type(title) != types.StringType:
            try:
                title = title.encode('utf-8')
            except Exception,e:
                self.lasterror = 'encode question fail.%s'%e
        return hashlib.md5(title).hexdigest()
    
    def commit(self):
        if not self.question:
            self.lasterror = 'No question infomation.'
            return False
        return self.setquestion(**self.question)
    
    def getquestion(self,qid):
        return self.get(_id=qid)
    
    def getnewestquestions(self,typeid=0,skip=0,limit=10,sortfield='timestamp',sortmethod=pymongo.DESCENDING):
        where = {'typeid':typeid} if typeid else {}
        return self.filter(where, skip, limit, sortfield,sortmethod)
    
    def getunanswers(self,typeid=0,skip=0,limit=10,sortfield='timestamp',sortmethod=pymongo.DESCENDING):
        where = { 'typeid':typeid , 'answers':{'$exists':False} } if typeid else { 'answers':{ '$exists':False } }
        return self.filter(where, skip, limit, sortfield,sortmethod)
    
    def getunrightquestions(self,typeid=0,skip=0,limit=10,sortfield='timestamp',sortmethod=pymongo.DESCENDING):
        where = { 'typeid':typeid, 'rightanswer':{'$exists':False} } if typeid else { 'rightanswer':{'$exists':False} }
        return self.filter(where, skip, limit, sortfield,sortmethod)
        
    def gettagquestions(self,tag,skip=0,limit=10,sortfield='timestamp',sortmethod=pymongo.DESCENDING):
        where = {'tags':tag}
        return self.filter(where,skip,limit,sortfield,sortmethod)
    
    def addanswer(self,qid,**answer):
        if not answer.has_key('answer') or not answer.has_key('uid'):
            return False
        answer['timestamp'] = time.time()
        if type(qid) != types.StringType:
            qid = qid.encode('utf-8')
        data = self.cache.get(qid)
        if data:
            data = cPickle.loads(data)
            if data.has_key('answers'):
                data['answers'].append(answer)
            else:
                data['answers'] = [answer,]
            self.cache.set(qid,cPickle.dumps(data),time=self.expire)
        res = self.db.update({'_id':qid}, {'$push':{'answers':answer}} , safe=True)
#        if not SearchEngine(' '.join(( answer['uid'] , answer['answer'] )),qid,qid).insert():
#            self.lasterror = 'Add answer index into searchengine fail. at QuestionModel:addanswer'
        return res['updatedExisting']
            
    def search(self,s,skip=0,limit=10):
        return searchengine.search(s,skip=skip,limit=limit)
    
    def setquestion(self,**question):
        if not question.has_key('title') or not question.has_key('uid'):
            return False
        question['_id'] = self.__hash_question__(question['title'])
        if 'tags' in question:
            tags = question['tags']
        for tag in tags:
            app.signal_addtagscore.send(__name__,tag=tag)
        self.db.ensure_index([('uid',pymongo.DESCENDING),
                              ('title',pymongo.DESCENDING),
                              ('tags',pymongo.DESCENDING)])
        result = self.save(**question)
#        raise TypeError,self.lasterror
#        if not SearchEngine(searchindex,question['_id'],question).insert():
#            self.lasterror = 'index question document \'%s\' fail'%question['title']
        return result and question['_id'] or False    
        
               
if __name__ == '__main__':
#    print __isenglish('Key names in inserted documents are limited as follows')               
#    print __isenglish('广东广东')
#    print __seg('Key names in inserted documents are limited as follows')
#    print __seg('收集最最精品的各类淘宝皇冠店')
#    print setquestion(uid='alanyang54@gmail.com',title='I love ida very much make love with him .. fuck him')
    with app.test_request_context():
        print setquestion(uid='alanyang54@gmail.com',title='I love ida very much make love with him .. fuck him')
        print 
        for i in getnewestquestions():
            print i
        import time
        begin = time.time()
        result = searchquestion('ida very make love')
        for r in result:print r['data'] , r['percent']
        print time.time() - begin
    
               
               
               
               
               
